﻿using Masa.BuildingBlocks.Dispatcher.IntegrationEvents;
using Masa.Contrib.Dispatcher.IntegrationEvents;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics.CodeAnalysis;
using RabbitMQ.Client;
using System.Text;
using Newtonsoft.Json;

namespace Sckf.Contrib.Dispatcher.IntegrationEvents.RabbitMq
{
    public class Publisher : IPublisher
    {
        private readonly IServiceProvider _serviceProvider;
        private IConnection? _rabbitMqClient;
        public IConnection RabbitMqClient => _rabbitMqClient ??= _serviceProvider.GetRequiredService<IConnection>();
        private readonly string _pubSubName;
        private readonly string _appId;
        private readonly ILogger<Publisher>? _logger;

        [ExcludeFromCodeCoverage]
        public Publisher(IServiceProvider serviceProvider, string pubSubName, string appId, string? daprAppId)
        {
            _serviceProvider = serviceProvider;
            _logger = serviceProvider.GetService<ILogger<Publisher>>();
            _pubSubName = pubSubName;
            _appId = appId;
        }


        public async Task PublishAsync<T>(string topicName, T @event, IntegrationEventExpand? eventMessageExpand, CancellationToken stoppingToken = default)
        {
            _logger?.LogDebug("----- Integration event publishing is in progress from {AppId}", _appId);
            using (var channel = RabbitMqClient.CreateModel())
            {              
                // 声明一个交换器，这里使用主题交换器
                channel.ExchangeDeclare($"exchange_{_pubSubName}", "topic", durable: true, autoDelete: false, arguments: null);

                // 声明一个队列，并设置消息过期时间和队列中消息的保密模式
                channel.QueueDeclare($"queue_{topicName}", durable: true, exclusive: false, autoDelete: false, arguments: null);

                // 将队列绑定到交换器上
                channel.QueueBind($"queue_{topicName}", $"exchange_{_pubSubName}", "routingKey", null);

                // 消息内容
                var message = JsonConvert.SerializeObject(@event);
                var body = Encoding.UTF8.GetBytes(message);

                // 发布消息到交换器，并指定一个路由键
                channel.BasicPublish($"exchange_{_pubSubName}", "routingKey", null, body);

                Console.WriteLine(" [x] Sent '{0}':'{1}'", "topic_logs", message);

            }
            _logger?.LogDebug("----- Publishing integration event from {AppId} succeeded and Event is {Event}", _appId, @event);
        }
    }
}